/*********************************************************************************
 *      Copyright:  (C) 2022 Zhang Changxing<ZhangChangxingVIP@163.com>
 *                  All rights reserved.
 *
 *       Filename:  serial_init.c
 *    Description:  This file function mainly implements the serial port initialization.
 *                 
 *        Version:  1.0.0(07/28/2022)
 *         Author:  Zhang Changxing <ZhangChangxingVIP@163.com>
 *      ChangeLog:  1, Release initial version on "07/28/2022  01:33:25 AM"
 *                 
 ********************************************************************************/



#include "sms.h"


/*--------------------------------------------------------------
 *   description:   Open the serial port File
 *          args:   $ttyusb_ctx:    Serial port property context
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int tty_open(ttyusb_ctx_t *ttyusb_ctx)
{
    if (!ttyusb_ctx)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    ttyusb_ctx->fd = open(ttyusb_ctx->serial_name, O_RDWR|O_NOCTTY|O_NONBLOCK);
    if (ttyusb_ctx->fd < 0)
    {
        log_error("[%s]Open serial file failure:%s\n", __func__, strerror(errno));
        return -2;
    }

    if (!isatty(ttyusb_ctx->fd))
    {
        log_error("[%s]%s is not a terminal equipment!\n", __func__, ttyusb_ctx->serial_name);
        return -3;
    }

    log_info("[%s]Open %s successfully!\n", __func__, ttyusb_ctx->serial_name);
    return 0;
}


/*--------------------------------------------------------------
 *   description:   Closing the serial port File
 *          args:   $ttyusb_ctx:    Serial port property context
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int tty_close(ttyusb_ctx_t *ttyusb_ctx)
{
    int retval = -1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    retval = tcflush(ttyusb_ctx->fd, TCIOFLUSH);
    if (retval < 0)
    {
        log_error("[%s]Failed to clear the input/output buffer:%s\n", __func__, strerror(errno));
        return -2;
    }
    
    retval = tcsetattr(ttyusb_ctx->fd, TCSANOW, &(ttyusb_ctx->old_termios));
    if (retval < 0)
    {
        log_error("[%s]Set old termios failure:%s\n", __func__, strerror(errno));
        return -3;
    }

    close(ttyusb_ctx->fd);
    
    printf("Excute tty_close() successfully!\n");

    return 0;
}


/*--------------------------------------------------------------
 *   description:   Example Initialize the serial port properties
 *          args:   $ttyusb_ctx:    Serial port property context
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int tty_init(ttyusb_ctx_t *ttyusb_ctx)
{
    int     retval = -1;
    char    baudrate_buf[32] = {0};
    struct  termios new_termios;

    if (!ttyusb_ctx)
    {
        log_error("The argument invalid!\n");
        return -1;
    }

    memset(&new_termios, 0, sizeof(new_termios));
    memset(&(ttyusb_ctx->old_termios), 0, sizeof(ttyusb_ctx->old_termios));

    retval = tcgetattr(ttyusb_ctx->fd, &(ttyusb_ctx->old_termios));
    if (retval < 0)
    {
        log_error("Failed to obtain the current serial port properties!\n");
        return -2;
    }

    retval = tcgetattr(ttyusb_ctx->fd, &new_termios);
    if (retval < 0)
    {
        log_error("Failed to obtain the current serial port properties!\n");
        return -3;
    }

    new_termios.c_cflag |= CLOCAL;//忽略解调器线路状态

    new_termios.c_cflag |= CREAD;

    new_termios.c_cflag &= ~CSIZE;//启动接收器，能够从串口中读取输入数据

    new_termios.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    /* 
     * ICANON: 标准模式
     * ECHO: 回显所输入的字符
     * ECHOE: 如果同时设置了ICANON标志，ERASE字符删除前一个所输入的字符，WERASE删除前一个输入的单词
     * ISIG: 当接收到INTR/QUIT/SUSP/DSUSP字符，生成一个相应的信号
     *
     * */

    new_termios.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
    /* 
     * BRKINT: BREAK将会丢弃输入和输出队列中的数据(flush)，并且如果终端为前台进程组的控制终端，则BREAK将会产生一个SIGINT信号发送到这个前台进程组
     * ICRNL: 将输入中的CR转换为NL
     * INPCK: 允许奇偶校验
     * ISTRIP: 剥离第8个bits
     * IXON: 允许输出端的XON/XOF流控
     *
     * */

     /* OPOST: 表示处理后输出，按照原始数据输出 */ 
    new_termios.c_oflag &= ~(OPOST);

    if (ttyusb_ctx->baudrate)
    {
        snprintf(baudrate_buf, sizeof(baudrate_buf), "B%d", ttyusb_ctx->baudrate);
        cfsetispeed(&new_termios, (int)baudrate_buf);
        cfsetospeed(&new_termios, (int)baudrate_buf);
    }
    else
    {
        cfsetispeed(&new_termios, B115200);
        cfsetospeed(&new_termios, B115200);
    }

    switch (ttyusb_ctx->databits)
    {
        case 5:
        {
            new_termios.c_cflag |= CS5;
            break;
        }

        case 6:
        {
            new_termios.c_cflag |= CS6;
            break;
        }

        case 7:
        {
            new_termios.c_cflag |= CS7;
            break;
        }

        case 8:
        {
            new_termios.c_cflag |= CS8;
            break;
        }

        default:
        {
            new_termios.c_cflag |= CS8;
            break; 
        }
    }

#if 1
    switch(ttyusb_ctx->parity)
    {
        case 'n':
        case 'N':
        {
            new_termios.c_cflag &= ~PARENB;
            break;
        }

        case 'o':
        case 'O':
        {
            new_termios.c_cflag |= (PARODD | PARENB);
            break;
        }

        case 'e':
        case 'E':
        {
            new_termios.c_cflag &= ~PARENB;
            new_termios.c_cflag &= ~PARODD;
        }

        case 'b':
        case 'B':
        {
            new_termios.c_cflag &= ~PARENB;
            new_termios.c_cflag &= ~CSTOP;
        }

        default:
        {
            new_termios.c_cflag &= ~PARENB;
            break;
        }
    }

    switch(ttyusb_ctx->stopbits)
    {
        case 1:
        {
            new_termios.c_cflag &= ~CSTOPB;
            break;
        }

        case 2:
        {
            new_termios.c_cflag |= CSTOPB;
            break;
        }

        default:
        {
            new_termios.c_cflag &= ~CSTOPB;
            break;
        }
    }
#endif


    //MIN =0 TIME =0 时，如果有数据可读，则read最多返回所要求的字节数，如果无数据可用，则read立即返回0；
    new_termios.c_cc[VTIME] = 0;
    new_termios.c_cc[VMIN] = 0;

    ttyusb_ctx->msend_len = 128;

    retval = tcflush(ttyusb_ctx->fd, TCIOFLUSH);
    if (retval < 0)
    {
        log_error("Failed to clear the input/output buffer:%s\n", strerror(errno));
        return -3;
    }

    retval = tcsetattr(ttyusb_ctx->fd, TCSANOW, &new_termios);
    if(retval < 0)
    {
        log_error("Failed to set new properties of the serial port:%s\n", strerror(errno));
        return -4;
    }

    printf("[%s]Successfully set new properties of the serial port!\n", __func__);
    return 0;
}


/*--------------------------------------------------------------
 *   description:   Sending data to the serial port
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $send_buf       Buffer address for data to be sent
 *                  $sbuf_len       The length of the send_buf
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int tty_send(ttyusb_ctx_t *ttyusb_ctx, char *send_buf, int sbuf_len)
{
    int     retval = -1;
    int     write_rv = 0;
    char    *ptr = NULL, *end = NULL;


    if (!ttyusb_ctx || !send_buf || (sbuf_len < 0))
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    if (sbuf_len > ttyusb_ctx->msend_len)
    {
        ptr = send_buf;
        end = send_buf + sbuf_len;
        do
        {   
            if(ttyusb_ctx->msend_len <(end-ptr))
            {
                retval = write(ttyusb_ctx->fd, ptr, ttyusb_ctx->msend_len);

                if ((retval <= 0) || (retval != ttyusb_ctx->msend_len))
                {
                    log_error("[%s]Write data to fd[%d] failure:%s\n", __func__, ttyusb_ctx->fd, strerror(errno));
                    return -2;
                }

                write_rv += retval;
                ptr += ttyusb_ctx->msend_len;
            }
            else
            {
                retval = write(ttyusb_ctx->fd, ptr, (end - ptr));

                if ((retval <= 0) || (retval != (end - ptr)))
                {
                    log_error("[%s]Write data to fd[%d] failure:%s\n",__func__, ttyusb_ctx->fd, strerror(errno));
                    return -3;
                }

                write_rv += retval;
                ptr += (end - ptr);
            }
            
        }while(ptr < end);
        
    }
    else
    {
        retval = write(ttyusb_ctx->fd, send_buf, sbuf_len);
        if((retval <= 0) || (retval != sbuf_len))
        {
            log_error("[%s]Write data to fd[%d] failure:%s\n", __func__, ttyusb_ctx->fd, strerror(errno));
            return -4;
        }
        write_rv += retval;
    }

    log_info("[%s]send_buf:%s\n", __func__ , send_buf);
    log_info("[%s]write_rv: %d\n", __func__ , write_rv);

    return write_rv;
}



/*--------------------------------------------------------------
 *   description:   Receive data from the serial port
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $recv_buf       Buffer address for data to be receive
 *                  $rbuf_len       The length of the recv_buf
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int tty_recv(ttyusb_ctx_t *ttyusb_ctx, char *recv_buf, int rbuf_len)
{
    int     read_rv = -1;
    int     rv_fd = -1;
    fd_set  rdset;
    struct  timeval time_out;

    if (!ttyusb_ctx || (rbuf_len < 0))
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }
    
    if (ttyusb_ctx->timeout)
    {
        time_out.tv_sec = (time_t)ttyusb_ctx->timeout;
        time_out.tv_usec = 0;
        FD_ZERO(&rdset);
        FD_SET(ttyusb_ctx->fd, &rdset);

        rv_fd = select(ttyusb_ctx->fd + 1, &rdset, NULL, NULL, &time_out);
        if(rv_fd < 0)
        {
            log_error("[%s]Select() listening for file descriptor error!\n", __func__);
            return -2;
        }
        else if(rv_fd == 0)
        {
            log_error("[%s]Select() listening for file descriptor timeout!\n", __func__);
            return -3;
        }
    }
    
    usleep(1000);
    read_rv = read(ttyusb_ctx->fd, recv_buf, rbuf_len);
    if (read_rv <= 0)
    {
        log_error("[%s]Read data from fd[%d] failure:%s\n", __func__, ttyusb_ctx->fd, strerror(errno));
        //return -4;
    }

    log_debug("[%s]recv_buf:%s\n", __func__, recv_buf);
    
    return read_rv;
}



/*---------------------------------------------------------------------------
 *   description:   It is used to send the AT command, receive and judge the return information
 *          args:   $ttyusb_ctx:        Serial port property context
 *                  $at_buf:            A buffer that holds AT instructions
 *                  $expect_buf:        The string you expect to receive
 *                  $return_buf:        The address of the buffer that receives 
 *                  the returned information
 *                  $return_buf_len:   return_buf length
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int send_at_cmd(ttyusb_ctx_t *ttyusb_ctx, char *at_buf, const char *expect_buf, char *return_buf, int return_buf_len)
{
    char   temp_buf[512] = {0};

    if (!at_buf || !expect_buf)
    {
        log_error("Unable to send AT commond,Invalid parameter.\n");
        return -1;
    }

    if(tty_send(ttyusb_ctx, at_buf, strlen(at_buf)) < 0)
    {
        log_error("Send AT commond failed:%s\n",strerror(errno));
        return -2;
    }
    
    usleep(10000);
    if(return_buf && return_buf_len)
    {
        if (tty_recv(ttyusb_ctx, return_buf, return_buf_len) <= 0)
        {
            log_error("Recving message failed:%s\n",strerror(errno));
            return -3;
        }
        log_info("return_buf:%s\n", return_buf);
        if (!strstr(return_buf, expect_buf))
        {
            log_error("Can't find what you expect to receive[%s]\n", expect_buf);
            return -4;
        }
    }
    else
    {
        if (tty_recv(ttyusb_ctx, temp_buf, sizeof(temp_buf)) <= 0)
        {
            log_error("Recving message failed:%s\n",strerror(errno));
            return -3;
        }
        log_info("temp_buf:%s\n", temp_buf);
        if (!strstr(temp_buf, expect_buf))
        {
            log_error("Can't find what you expect to receive[%s]\n", expect_buf);
            return -4;
        }
        
    }
    
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the serial port is available
 *          args:   $ttyusb_ctx:        Serial port property context
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int check_tyy_ready(ttyusb_ctx_t *ttyusb_ctx)
{
    int send_rv = -1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    send_rv = send_at_cmd(ttyusb_ctx, "AT\r", "OK", NULL, 0);
    if (0 != send_rv)
    {
        log_error("[%s]The serial port is not ready!\n", __func__);
        return -2;
    }

    log_info("[%s]The serial port is ok!\n", __func__);
    
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the SIM card exists
 *          args:   $ttyusb_ctx:        Serial port property context
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int check_sim_exist(ttyusb_ctx_t *ttyusb_ctx)
{
    int send_rv = -1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    send_rv = send_at_cmd(ttyusb_ctx, "AT+CPIN?\r", "READY", NULL, 0);
    if (send_rv < 0)
    {
        log_error("[%s]The SIM card is not exist\n", __func__);
        return -2;
    }

    log_info("[%s]The SIM card is exist!\n", __func__);
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the SIM has been registered
 *          args:   $ttyusb_ctx:        Serial port property context
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int check_sim_login(ttyusb_ctx_t *ttyusb_ctx)
{
    int send_rv1 = -1;
    int send_rv2 = -1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    send_rv1 = send_at_cmd(ttyusb_ctx, "AT+CREG?\r", "0,1", NULL, 0);
    send_rv2 = send_at_cmd(ttyusb_ctx, "AT+CREG?\r", "0,3", NULL, 0);
    if (send_rv1 && send_rv2)
    {
        log_error("[%s]The SIM card does not exist!\n", __func__);
        return -2;
    }

    log_info("[%s]SIM card is exist!\n", __func__);
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the SIM card signal is normal
 *          args:   $ttyusb_ctx:        Serial port property context
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int check_sim_signal(ttyusb_ctx_t *ttyusb_ctx)
{
    int     send_rv = -1;
    char    return_buf[256] = {0};
    char    separator[] = " ,";
    int     signal = -1;
    char    *token = NULL;
    int     i = 1;

    if (!ttyusb_ctx)
    {
        printf("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    send_rv = send_at_cmd(ttyusb_ctx, "AT+CSQ\r", "+CSQ", return_buf, sizeof(return_buf));
    if (send_rv < 0)
    {
        printf("[%s]Not found SIM signal!\n", __func__);
        return -2;
    }

    log_debug("[%s]return_buf:%s\n", __func__, return_buf);

    #if 1
   
    token = strtok(return_buf, separator);
    while (token != NULL)
    {
        ++i;
        token = strtok(NULL, separator);
        log_debug("i: %d \ntoken:%s\n", i , token);

        if(2 == i)
        {
            signal = atoi(token);
            if ((signal < 8) || (signal > 31))
            {
                log_error("[%s]The signal1 value is: %d, is not normal!\n", __func__, signal);
                return -3;
            }
            else
            {
                log_info("[%s]The signal1 value is: %d, normal!\n", __func__, signal);
                break;
            }
        }

    }
    #endif

    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the serial port and SIM are ready
 *          args:   $ttyusb_ctx:        Serial port property context
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int check_all_ready(ttyusb_ctx_t *ttyusb_ctx)
{
    //Ensure that the serial port is available
    if (check_tyy_ready(ttyusb_ctx) < 0)
        return -1;
    log_info("[%s]tyy is ok\n", __func__);

    //If the serial port can communicate, the SIM card can be detected
    if (check_sim_exist(ttyusb_ctx) < 0)
        return -2;
    log_info("[%s]SIM is exist!\n", __func__);

    //Check whether the SIM card is registered
    if (check_sim_login(ttyusb_ctx) < 0)
        return -3;
    log_info("[%s]SIM is login!\n", __func__);

    //Check the SIM card signal
    if (check_sim_signal(ttyusb_ctx) < 0)
        return -4;
    log_info("[%s]SIM signal is ok!\n", __func__);

    log_info("[%s]SIM and tty are ready!\n", __func__);
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Check whether the serial port and SIM are ready
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $center_buf     Store the obtained center number
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int get_center_number(ttyusb_ctx_t *ttyusb_ctx, char *center_buf)
{
    int     send_rv = -1;
    char    return_buf[256] = {0};
    char    separator[] = "\"";
    char    *token = NULL;
    int     i = 1;

    if ((!ttyusb_ctx) || (!center_buf))
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    #if 1
    send_rv = send_at_cmd(ttyusb_ctx, "AT+CSCA?\r", "+CSCA", return_buf, sizeof(return_buf));
    if (send_rv < 0)
    {
        log_error("[%s]Not found center number!\n", __func__);
        return -2;
    }

    token = strtok(return_buf, separator);
    while (token != NULL)
    {
        ++i;
        token = strtok(NULL, separator);
        log_debug("[%s]i: %d \ntoken:%s\n", __func__, i , token);
        if(2 == i)
        {
            strncpy(center_buf, token, strlen(token));
            break;
        }

    }
    #endif

    printf("[%s]The center number:%s\n", __func__, center_buf);
    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   The Text format is used to send short messages
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $phone_buf      Store the obtained target number
 *                  $sms_buf        Information to be sent
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int send_text_sms(ttyusb_ctx_t *ttyusb_ctx, char *phone_buf, char *sms_buf)
{
    char    temp_buf[256] = {0};

    if (!ttyusb_ctx || !phone_buf || !sms_buf)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    if (send_at_cmd(ttyusb_ctx, "AT+CMGF=1\r", "OK", NULL, 0))
    {
        log_error("[%s]Send at command [AT+CMGF=1] to tty failure!\n", __func__);
        return -2;
    }

    printf("[%s]Send at command [AT+CMGF=1] to tty successfully!\n\n\n", __func__);
    sprintf(temp_buf, "AT+CMGS=\"%s\"\r", phone_buf);


    if (send_at_cmd(ttyusb_ctx, temp_buf, ">", NULL, 0))
    {
        log_error("[%s]Receive > failure!\n", __func__);
        return -3;
    }

    printf("[%s]Recv the '>' ok!\n", __func__);
    strcat(sms_buf, "\x1a");

    if (send_at_cmd(ttyusb_ctx, sms_buf, "OK", NULL, 0))
    {
        log_error("[%s]Failed to send SMS messages!\n", __func__);
        return -4;
    }

    log_info("[%s]Successed to send SMS messages!\n", __func__);

    return 0;
}


/*---------------------------------------------------------------------------
 *   description:   Send short messages in PDU format
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $phone_buf      Store the obtained target number
 *                  $sms_buf        Information to be sent
 *  return value:   <0: failure,    =0: ok 
 *---------------------------------------------------------------------------*/
int send_pdu_sms(ttyusb_ctx_t *ttyusb_ctx, char *phone_buf, char *sms_buf)
{
    char    center_buf[256] = {0};
    char    pdu_buf[512] = {0};
    char    at_buf[256] = {0};
    int     cmgs_length = 0;

    if (!ttyusb_ctx || !phone_buf || !sms_buf)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    if (get_center_number(ttyusb_ctx, center_buf) < 0)
    {
        log_error("[%s]Get center number failure!\n", __func__);
        return -2;
    }

    if (pdu_packet(center_buf, phone_buf, sms_buf, pdu_buf, &cmgs_length) < 0)
    {
        log_error("[%s]Failed to package SMS messages into PDU format\n", __func__);
        return -3;
    }

    if (send_at_cmd(ttyusb_ctx, "AT+CMGF=0\r", "OK", NULL,  0) < 0)
    {
        log_error("[%s]Send at command [AT+CMGF=0\r] failure!\n", __func__);
        return -4;
    }

    sprintf(at_buf, "AT+CMGS=%d\r", cmgs_length);
    if (send_at_cmd(ttyusb_ctx, at_buf, ">", NULL,  0) < 0)
    {
        log_error("[%s]Send at command [AT+CMGS=%d\r] failure!\n", __func__, cmgs_length);
        return -5;
    }

    strcat(pdu_buf,"\x1a");
    log_info("[%s] pdu_buf = %s\n",__func__ , pdu_buf);

    if (send_at_cmd(ttyusb_ctx, pdu_buf, "OK", NULL,  0))
    {
        log_error("[%s]Send pud sms failure!\n", __func__);
        return -6;
    }
    
    log_info("[%s]Send pud sms successfully!\n", __func__);
    
    return 0;
}



/*-------------------------------------------------------------------------
 *   description:   Get and process the center number
 *          args:   $center_buf:    Receive the processed center number
 *  return value:   <0: failure,    =0:ok 
 *-------------------------------------------------------------------------*/
int processing_center_number(char *center_buf)
{
    char    temp_buf[256] = {0};
    int     i = 0;
    int     temp =0;

    if (!center_buf)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    strcpy(center_buf, &center_buf[1]);
    strcat(center_buf, "F");

    for (i = 0; i < strlen(center_buf); i += 2)
    {
        temp = center_buf[i];
        center_buf[i] = center_buf[i+1];
        center_buf[i+1] = temp;
    }

    snprintf(temp_buf, strlen(center_buf)+strlen("0891")+1, "0891%s", center_buf);
    memset(center_buf, 0 , sizeof(center_buf));
    strncpy(center_buf, temp_buf, strlen(temp_buf));

    log_debug("[%s]Processing center number succeeded:%s\n", __func__, center_buf);

    return 0;
}


/*-------------------------------------------------------------------------
 *   description:   Get and process the target number
 *          args:   $center_buf:    Receive the processed center number
 *  return value:   <0: failure,    =0:ok 
 *-------------------------------------------------------------------------*/
int processing_phone_number(char *phone_buf)
{
    char    temp_buf[256] = {0};
    int     i = 0;
    int     temp =0;

    if (!phone_buf)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    strcpy(phone_buf, &phone_buf[1]);
    strcat(phone_buf, "F");

    for (i = 0; i < strlen(phone_buf); i += 2)
    {
        temp = phone_buf[i];
        phone_buf[i] = phone_buf[i+1];
        phone_buf[i+1] = temp;
    }

    sprintf(temp_buf, "11000D91%s000800", phone_buf);
    memset(phone_buf, 0, sizeof(phone_buf));
    strncpy(phone_buf, temp_buf, strlen(temp_buf));

    log_info("[%s]Phone_number processing succeeded:%s\n", __func__, phone_buf);

    return 0;
}


/*-------------------------------------------------------------------------
 *   description:   Convert UTF8 encoding format to Unicode encoding format
 *          args:   $utf8_buf:      UTF8 Encoding format string
 *                  $unicode_buf    Stores the address of the Unicde coding buffer
 *                  $len            Unicde Indicates the encoded byte length
 *  return value:   <0: failure,    =0:ok 
 *-------------------------------------------------------------------------*/
int utf8_to_unicode(char *utf8_buf, char *unicode_buf, int *len)
{
    char    Byte1, Byte2, Byte3, Byte4;
    char    *ptr = unicode_buf;
    int     i = 0;
    *ptr    = 0;

    if (!utf8_buf)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }
    
    while (*utf8_buf)
    {
        if ((*utf8_buf & 0x80) == 0x00)
        {
            ptr++;
            *ptr = *utf8_buf;
            ptr++;
            utf8_buf++;
            i +=2;
        }
        else if ((*utf8_buf & 0xE0) == 0xC0)
        {
            Byte1 = *utf8_buf;
            Byte2 = *(utf8_buf + 1);

            if ((Byte2 & 0xC0) != 0x80)
                return -2;
            
            *ptr = ((Byte1 >> 2) & 0x07);
            ptr++;
            *ptr = (Byte1 << 6) + (Byte2 & 0x3F);
            ptr++;
            utf8_buf +=2;
            i +=2;
        }
        else if ((*utf8_buf & 0xF0) == 0xE0)
        {
            Byte1 = *utf8_buf;
            Byte2 = *(utf8_buf + 1);
            Byte3 = *(utf8_buf + 2);

            *ptr = (Byte1 << 4) + ((Byte2 >> 2) & 0x0F);
            ptr++;
            *ptr = (Byte2 << 6) + (Byte3 & 0x3F);
            ptr++;
            utf8_buf += 3;
            i += 2;
        }
        else if ((*utf8_buf & 0xF8) == 0xF0)
        {
            Byte1 = *utf8_buf;
            Byte2 = *(utf8_buf + 1);
            Byte3 = *(utf8_buf + 2);
            Byte4 = *(utf8_buf + 3);

            *ptr = ((Byte1 & 0x07) << 2) + ((Byte2 >> 4) & 0x03);
            ptr++;
            *ptr = (Byte2 << 4) + ((Byte3 >> 2) & 0x0F);
            ptr++;
            *ptr = (Byte2 <<6) + (Byte4 & 0x3F);
            utf8_buf +=3;
            i += 4;
        }
    }

    *len = i;

    //log_debug("strlen(unicode_buf):%d\n", strlen(unicode_buf));

    return 0;
}


/*-------------------------------------------------------------------------
 *   description:   Byte stream character stream
 *          args:   $src_buf:       Byte stream buffer address
 *                  $dest_buf:      Character stream buffer address
 *                  $source_len:    Byte stream buffer length
 *  return value:   <0: failure,    =0:ok 
 *-------------------------------------------------------------------------*/
int hex_to_str(char *dest_buf, char *src_buf, int src_len)
{
    int i = 0;
    char *ptr = dest_buf;

    for (i; i< src_len; i++)
    {
        log_debug("src_buf[%d]:%02x\n", i, src_buf[i]);
        sprintf(ptr, "%02x",src_buf[i]);
        ptr += 2;
    }

    return 0;
}



/*-------------------------------------------------------------------------
 *   description:   The center number, destination number, and short message 
 *                  are packaged into a PDU package
 *          args:   $center_buf:    Address of the center number buffer that 
 *                  has been processed
 *                  $phone_buf:     Target number buffer address already processed
 *                  $sms_buf:       Address of the processed SMS buffer
 *                  $pdu_buf:       Address of the packed PDU buffer
 *                  $cmgs_length    The sum of the length of the target number 
 *                  and the data section
 *  return value:   <0: failure,    =0:ok 
 *------------------------------------------------------------------------*/
int pdu_packet(char *center_buf, char *phone_buf, char *sms_buf, char *pdu_buf, int *cmgs_length)
{
    char    temp[512] = {0};
    char    dest_buf[512] = {0};
    char    unicode_buf[512] = {0};
    int     unicode_len = 0;

    if (!center_buf || !phone_buf || !sms_buf)
    {
        log_error("[%s]The argument invalid!\n", __func__);
        return -1;
    }

    processing_center_number(center_buf);
    printf("[%s]center number:%s\n", __func__, center_buf);

    //printf("[%s]phone_buf:%s\n", __func__, phone_buf);
    processing_phone_number(phone_buf);
    printf("[%s]phone number:%s\n", __func__, phone_buf);


    printf("[%s]sms_buf:%s\n", __func__, sms_buf);
    utf8_to_unicode(sms_buf, unicode_buf, &unicode_len);

    hex_to_str(dest_buf, unicode_buf, unicode_len);
    printf("[%s]SMS PDU:%s\n", __func__, dest_buf);

    sprintf(temp, "%s%02x%s", phone_buf, strlen(dest_buf)/2, dest_buf);
    *cmgs_length  = strlen(temp)/2;

    strncat(pdu_buf, center_buf, strlen(center_buf));
    strncat(pdu_buf, temp, strlen(temp));
    

    log_info("[%s]cmgs_length:%d\n pdu_buf:%s\n", __func__, *cmgs_length, pdu_buf);

    return 0;
}



/*--------------------------------------------------------------
 *   description:   Character stream byte stream
 *          args:   $source:    Character stream buffer address
 *                  $dest  :    Byte stream buffer address
 *                  $source_len:Character stream buffer length
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int str_to_hex(char *source, char *dest, int source_len)
{
    char    highbyte;//High byte
    char    lowbyte;//The low byte
    int     i = 0;

    //In the received message string, there are only numbers and letters, so only numbers and letters can be processed
    for (i; 2*i < source_len; i ++)
    {
        highbyte = toupper(source[i*2]);//Convert all lowercase letters to uppercase letters
        lowbyte = toupper(source[i*2 +1]);

        if(highbyte <= 0x39)
            highbyte -= 0x30;
        else
            highbyte -= 0x37;

        if(lowbyte <= 0x39)
            lowbyte -= 0x30;
        else
            lowbyte -= 0x37;

        dest[i] = (highbyte << 4) | lowbyte;
        //log_debug("dest[%d]=%02x\n",i, dest[i]);
    } 

    return 0;
}


/*--------------------------------------------------------------
 *   description:   Unicode encoding to UTF8 encoding
 *          args:   $unic_buf:    Unicode encoding buffer address
 *                  $unic_len:    Unicode encoding buffer length
 *                  $utf8_buf:    UTF8 Encoding buffer address
 *                  $utf8_len:    UTF8 Encoding buffer length
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int unicode_to_utf8(char *source, size_t source_len, char *dest, size_t dest_len)
{
    int     i = 0;
    char    temp;
    int     retval = -1;
    iconv_t cd;
    char    unicode_buf[512] = {0};
    

    if (!source)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }
    //log_debug("[%s]source:%s\n", __func__, source);

    str_to_hex(source, unicode_buf, strlen(source));

    for (i; i < sizeof(unicode_buf); i +=2)
    {
        temp = unicode_buf[i];
        unicode_buf[i] = unicode_buf[i+1];
        unicode_buf[i+1] = temp;
    }

    cd = iconv_open("UTF-8","UNICODE");
    if (cd < 0)
    {
        log_error("[%s]iconv_open() failure!\n", __func__);
        return -2;
    }

    char    *source_ptr = unicode_buf;
    

    retval =  iconv(cd, &source_ptr, &source_len, &dest, &dest_len);
    if(retval < 0)
    {
        log_error("[%s]Unicode to utf-8 failure:%s\n", __func__, strerror(errno));
        iconv_close(cd);
        return -3;
    }

    //log_debug("Unicode to utf-8 successfully:%s\n", dest);

    iconv_close(cd);
    return 0;
}


/*--------------------------------------------------------------
 *   description:   Used for Text format decoding
 *          args:   $source:        Character stream buffer address
 *                  $dest:          Destination buffer address
 *                  $source_len:    Character stream length
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int text_decod(char *source, char *dest, int source_len)
{
    char temp_buf[512] = {0};

    if (!source|| !dest)
    {
        log_error("[%s]Invalid argument.\n", __func__);
        return -1;
    }

    str_to_hex(source, temp_buf, source_len);
    decode7bit(temp_buf, dest, strlen(temp_buf));

    return 0;
}


/*--------------------------------------------------------------
 *   description:   This parameter is used to calculate the PDU 
 *                  center number, source number, and data length
 *          args:   $ptr:        Character stream buffer address
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int calculate_len(char *ptr)
{
    int len;
    int highbyte;
    int lowbyte;

    if (*ptr < 0x39)
        highbyte = (*ptr - 0x30)*16;
    else
        highbyte = (*ptr-0x37)*16;

    //log_debug("highbyte:%d\n", highbyte);

    ptr++;
    if (*ptr < 0x39)
        lowbyte = *ptr - 0x30;
    else
        lowbyte = *ptr - 0x37;

    //log_debug("lowbyte:%d\n", lowbyte);
    len = highbyte + lowbyte;
    //log_debug("len:%d\n", len);

    return len;
}


/*--------------------------------------------------------------
 *   description:   Get information about a specified number
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $sms_buf:       The address of the buffer where 
 *                  the returned information is stored
 *                  $sms_buf_len:   sms_buf length
 *                  $target_number: Destination number buffer address
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int get_specified_sms(ttyusb_ctx_t *ttyusb_ctx, char *sms_buf, int sms_buf_len, char *target_number)
{
    int     retval = -1;
    char    temp_buf[1024] = {0};
    char    *start_ptr = NULL;
    int     center_number_len = 0;
    char    phone_number[32] = {0};
    int     phone_len = 0;
    int     phone_flag = 0;
    int     encoding = 0;//编码
    int     data_len = 0;
    char    send_buf[128] = {0};
    char    time_buf[13] = {0};
    int     index = 0;
    int     j = 0;
    char    temp;
    char    data_buf[1024] = {0};
    int     sms_flag = 1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    retval = send_at_cmd(ttyusb_ctx, "AT+CSDH=1\r", "OK", NULL, 0);
    if(retval < 0)
    {
        log_error("[%s]Send command AT+CSDH=1 failure!\n", __func__);
        return -2;
    }
    

    while (1)
    {
        memset(send_buf, 0 , sizeof(send_buf));
        sprintf(send_buf, "AT+CMGR=%d\r", index);
        memset(temp_buf, 0, sizeof(temp_buf));

        retval = send_at_cmd(ttyusb_ctx, send_buf, "OK", temp_buf, sizeof(temp_buf));
        if(retval < 0)
        {
            log_error("[%s]There is no message %d\n", __func__, index);
            return -3;
        }

        start_ptr = strstr(temp_buf, "+CMGR");
        if(NULL == start_ptr)
        {
            log_error("[%s]There is no message %d\n", __func__, index);
            break;
        }


        start_ptr = strstr(start_ptr, "\r\n");
        start_ptr += 2;//Let the pointer point to the front of the PDU
        center_number_len = calculate_len(start_ptr);//Calculate the length of the center number
        start_ptr = start_ptr + 2 + center_number_len*2 + 2;
        phone_len = calculate_len(start_ptr);//Calculate the length of the source number
        //If the number is an odd number of digits, add an F calculation
        if(phone_len%2 != 0)
        {
            phone_len++;
            phone_flag = 1;
        }

        //Get the sender number
        strncpy(phone_number, start_ptr+2+2, phone_len);
        for(j = 0; j < phone_len; j +=2)
        {
            temp = phone_number[j];
            phone_number[j] = phone_number[j+1];
            if(phone_flag && ((phone_len -2) == j))
            {
                phone_number[j+1] ='\0';
            }
            else
            {
                phone_number[j+1] = temp;
            }
        }

        if(strncmp(target_number, phone_number, strlen(phone_number)))
        {
            
            start_ptr = NULL;
            index++;
            continue;
        }

        printf("PDU package:%s\n", temp_buf);
        printf("SMS Index:%d\n", index);
        printf("Sender:%s\n", phone_number);


        //log_debug("target_number:%s\n", target_number);
        start_ptr = start_ptr + 2 + 2 + phone_len  + 2;
        encoding = calculate_len(start_ptr);//Get the encoding format
        start_ptr = start_ptr + 2 ; 
        snprintf(time_buf, 12+1, "%s", start_ptr);

        printf("Receive time:");
        for(j = 0; j < 12; j +=2)
        {
            temp = time_buf[j];
            time_buf[j] = time_buf[j+1];
            time_buf[j+1] = temp;
            printf("-%c%c", time_buf[j], time_buf[j+1]);
        }
        printf("\n");
        
        start_ptr = start_ptr + 12 + 2;
        data_len = calculate_len(start_ptr);
        data_len = data_len*2;
        start_ptr = start_ptr +2;
        memset(data_buf, 0, data_len);
        snprintf(data_buf, data_len+1, "%s", start_ptr);

        //log_debug("The data PDU is %s\n", data_buf);
        memset(sms_buf, 0, sms_buf_len);
        if(encoding)
        {
            retval = unicode_to_utf8(data_buf, sizeof(data_buf), sms_buf, sms_buf_len);
        }
        else
        {
            text_decod(start_ptr, sms_buf, data_len);
            
        }

        printf("SMS:%s\n", sms_buf);
        start_ptr = NULL;
        index++;
        
        printf("-----------------------------------------------------------------------------------------------------\n");
            
    }

}


/*--------------------------------------------------------------
 *   description:   Get information about a specified number
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $sms_buf:       The address of the buffer where 
 *                  the returned information is stored
 *                  $sms_buf_len:   sms_buf length
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int get_all_sms(ttyusb_ctx_t *ttyusb_ctx, char *sms_buf, int sms_buf_len)
{
    int     retval = -1;
    char    temp_buf[1024] = {0};
    char    *start_ptr = NULL;
    int     center_number_len = 0;
    char    phone_number[32] = {0};
    int     phone_len = 0;
    int     phone_flag = 0;
    int     encoding = 0;
    int     data_len = 0;
    char    send_buf[128] = {0};
    char    time_buf[13] = {0};
    int     index = 0;
    int     j = 0;
    char    temp;
    char    data_buf[1024] = {0};

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument.\n", __func__);
        return -1;
    }

    retval = send_at_cmd(ttyusb_ctx, "AT+CSDH=1\r", "OK", NULL, 0);
    if(retval < 0)
    {
        log_error("[%s]Send command AT+CSDH=1 failure!\n", __func__);
        return -2;
    }


    while (1)
    { 
        memset(send_buf, 0 , sizeof(send_buf));
        sprintf(send_buf, "AT+CMGR=%d\r", index);
        memset(temp_buf, 0, sizeof(temp_buf));
        retval = send_at_cmd(ttyusb_ctx, send_buf, "+CMGR", temp_buf, sizeof(temp_buf));
        if(retval < 0)
        {
            printf("There is no index:%d\n", index);
            break;
            return -3;
        }
        start_ptr = strstr(temp_buf, "+CMGR");
        
        
        start_ptr = strstr(start_ptr, "\r\n");
        start_ptr += 2;//Let the pointer point to the front of the PDU
        center_number_len = calculate_len(start_ptr);//Calculate the length of the center number
        start_ptr = start_ptr + 2 + center_number_len*2 + 2;
        phone_len = calculate_len(start_ptr);//Calculate the length of the sender number

        //If the number is an odd number of digits, add an F calculation
        if(phone_len%2 != 0)
        {
            phone_len++;
            phone_flag = 1;
        }

        //Get the sender number
        strncpy(phone_number, start_ptr+2+2, phone_len);
        for(j = 0; j < phone_len; j +=2)
        {
            temp = phone_number[j];
            phone_number[j] = phone_number[j+1];
            if(phone_flag && ((phone_len -2) == j))
            {
                phone_number[j+1] ='\0';
            }
            else
            {
                phone_number[j+1] = temp;
            }
        }

        printf("PDU package:%s\n", temp_buf);
        printf("SMS Index:%d\n", index);
        printf("Sender:%s\n", phone_number);


        start_ptr = start_ptr + 2 + 2 + phone_len  + 2;
        encoding = calculate_len(start_ptr);//Get the encoding format
        start_ptr = start_ptr + 2 ;

        memset(time_buf, 0 ,sizeof(time_buf));
        snprintf(time_buf, 12+1, "%s", start_ptr);

        printf("Receive time:");
        for(j = 0; j < 12; j +=2)
        {
            temp = time_buf[j];
            time_buf[j] = time_buf[j+1];
            time_buf[j+1] = temp;
            printf("-%c%c", time_buf[j], time_buf[j+1]);
        }
        printf("\n");
        
        
        start_ptr = start_ptr + 12 + 2;
        
        data_len = calculate_len(start_ptr);
        data_len = data_len*2;
        start_ptr = start_ptr +2;
        memset(data_buf, 0, data_len);
        snprintf(data_buf, data_len+1, "%s", start_ptr);

        if(encoding)
        {
            memset(sms_buf, 0, sms_buf_len);
            retval = unicode_to_utf8(data_buf, sizeof(data_buf), sms_buf, sms_buf_len);
        }
        else
        {
            text_decod(start_ptr, sms_buf, data_len);
            
        }

        printf("SMS:%s\n", sms_buf);
        start_ptr = NULL;
        index++;

        printf("-----------------------------------------------------------------------------------------------------\n");
            
    }

}


/*--------------------------------------------------------------
 *   description:   Decoding by 7bit encoding
 *          args:   $source:    Source buffer address
 *                  $dest  :    The target buffer address
 *                  $source_len:Source buffer length
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int decode7bit(const unsigned char* source, char* dest, int source_len)
{
        int nsrc = 0;  
        int ndst = 0;
        int nbyte = 0;
        unsigned char nleft = 0;

        if (!source||!dest||(source_len<=0))
        {
            log_error("[%s]Invalid parameter\n",__func__);
            return -1;
        }
        
        while (nsrc < source_len)
        {
            *dest = ((*source << nbyte) | nleft) & 0x7f;
            nleft = *source >> (7-nbyte);
            dest++;
            ndst++;
            nbyte++;
            if(nbyte == 7)
            {
                *dest = nleft;
                dest++;
                ndst++;
                nbyte = 0;
                nleft = 0;
            }
            source++;
            nsrc++;
        }
        *dest = 0;

        return ndst;
}


/*--------------------------------------------------------------
 *   description:   Get information about a specified number
 *          args:   $ttyusb_ctx:    Serial port property context
 *                  $sms_buf:       The address of the buffer where 
 *                  $target_number: Destination number buffer address
 *  return value:   <0: failure,    =0:ok 
 *--------------------------------------------------------------*/
int delete_sms(ttyusb_ctx_t *ttyusb_ctx, char *target_number)
{
    int     retval = -1;
    char    temp_buf[1024] = {0};
    char    *start_ptr = NULL;
    int     center_number_len = 0;
    char    phone_number[32] = {0};
    int     phone_len = 0;
    int     phone_flag = 0;
    char    send_buf[128] = {0};
    char    time_buf[13] = {0};
    int     index = 0;
    int     j = 0;
    char    temp;
    char    data_buf[1024] = {0};
    int     sms_flag = 1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    retval = send_at_cmd(ttyusb_ctx, "AT+CSDH=1\r", "OK", NULL, 0);
    if(retval < 0)
    {
        log_error("[%s]Send command AT+CSDH=1 failure!\n", __func__);
        return -2;
    }
    

    while (1)
    {
        memset(send_buf, 0 , sizeof(send_buf));
        sprintf(send_buf, "AT+CMGR=%d\r", index);
        memset(temp_buf, 0, sizeof(temp_buf));

        retval = send_at_cmd(ttyusb_ctx, send_buf, "OK", temp_buf, sizeof(temp_buf));
        if(retval < 0)
        {
            log_error("[%s]There is no message %d\n", __func__, index);
            return -3;
        }

        start_ptr = strstr(temp_buf, "+CMGR");
        if(NULL == start_ptr)
        {
            log_error("[%s]There is no message %d\n", __func__, index);
            break;
        }

        start_ptr = strstr(start_ptr, "\r\n");
        start_ptr += 2;//Let the pointer point to the front of the PDU
        center_number_len = calculate_len(start_ptr);//Calculate the length of the center number
        start_ptr = start_ptr + 2 + center_number_len*2 + 2;
        phone_len = calculate_len(start_ptr);//Calculate the length of the sender number

        //If the number is an odd number of digits, add an F calculation
        if(phone_len%2 != 0)
        {
            phone_len++;
            phone_flag = 1;
        }

        //Get the sender number
        strncpy(phone_number, start_ptr+2+2, phone_len);
        for(j = 0; j < phone_len; j +=2)
        {
            temp = phone_number[j];
            phone_number[j] = phone_number[j+1];
            if(phone_flag && ((phone_len -2) == j))
            {
                phone_number[j+1] ='\0';
            }
            else
            {
                phone_number[j+1] = temp;
            }
        }

        if(strncmp(target_number, phone_number, strlen(phone_number)))
        {
            
            start_ptr = NULL;
            index++;
            continue;
        }

        memset(send_buf, 0 , sizeof(send_buf));
        sprintf(send_buf,"AT+CMGD=%d\r",index);
        retval = send_at_cmd(ttyusb_ctx, send_buf, "OK", NULL, 0);
        if(retval < 0)
        {
            log_error("[%s]Failed to delte the information\n", __func__);
            return -3;
        }
        printf("Delete message %d ok!\n",index);

        start_ptr = NULL;
        index++;
        
        printf("-----------------------------------------------------------------------------------------------------\n");
            
    }

}


int listen_index0(ttyusb_ctx_t *ttyusb_ctx, char *sms_buf, int sms_buf_len, char *target_number)
{
    int     retval = -1;
    char    temp_buf[1024] = {0};
    char    *start_ptr = NULL;
    int     center_number_len = 0;
    char    phone_number[32] = {0};
    int     phone_len = 0;
    int     phone_flag = 0;
    int     encoding = 0;//编码
    int     data_len = 0;
    int     index = 0;
    int     j = 0;
    char    temp;
    char    data_buf[1024] = {0};
    int     sms_flag = 1;

    if (!ttyusb_ctx)
    {
        log_error("[%s]Invalid argument!\n", __func__);
        return -1;
    }

    retval = send_at_cmd(ttyusb_ctx, "AT+CMGF=0\r", "OK", NULL, 0);
    if(retval < 0)
    {
        log_error("[%s]Send command AT+CMGF=0 failure!\n", __func__);
        return -2;
    }
    
    memset(temp_buf, 0, sizeof(temp_buf));
    
    retval = send_at_cmd(ttyusb_ctx,  "AT+CMGR=0\r", "OK", temp_buf, sizeof(temp_buf));
    if(retval < 0)
    {
        log_info("[%s]Send command AT+CMGR=0 failure!\n", __func__);
        return -3;
    }

    retval = send_at_cmd(ttyusb_ctx,  "AT+CMGD=0\r", "OK", NULL, 0);
    if(retval < 0)
    {
        log_info("[%s]Send command AT+CMGD=0 failure!\n", __func__);
        return -4;
    }

    start_ptr = strstr(temp_buf, "+CMGR");
    if(NULL == start_ptr)
    {
        log_error("[%s]There is no message %d\n", __func__, index);
        return -4;
    }

    
    start_ptr = strstr(start_ptr, "\r\n");
    start_ptr += 2;//Let the pointer point to the front of the PDU
    center_number_len = calculate_len(start_ptr);//Calculate the length of the center number
    
    start_ptr = start_ptr + 2 + center_number_len*2 + 2;
    phone_len = calculate_len(start_ptr);//Calculate the length of the source number
    //If the number is an odd number of digits, add an F calculation
    if(phone_len%2 != 0)
    {
        phone_len++;
        phone_flag = 1;
    }
    
    //Get the sender number


    strncpy(phone_number, start_ptr+2+2, phone_len);
    for(j = 0; j < phone_len; j +=2)
    {
        temp = phone_number[j];
        phone_number[j] = phone_number[j+1];
        if(phone_flag && ((phone_len -2) == j))
        {
            phone_number[j+1] ='\0';
        }
        else
        {
            phone_number[j+1] = temp;
        }
    }

    if(strncmp(target_number, phone_number, strlen(phone_number)))
    {
        
        return -4;
    }

    //printf("PDU package:%s\n", temp_buf);
    printf("SMS Index:%d\n", index);
    printf("Sender:%s\n", phone_number);


    //log_debug("target_number:%s\n", target_number);
    start_ptr = start_ptr + 2 + 2 + phone_len  + 2;
    encoding = calculate_len(start_ptr);//Get the encoding format
    start_ptr = start_ptr + 2 ; 
    
    start_ptr = start_ptr + 12 + 2;
    data_len = calculate_len(start_ptr);
    data_len = data_len*2;
    start_ptr = start_ptr +2;
    memset(data_buf, 0, data_len);
    snprintf(data_buf, data_len+1, "%s", start_ptr);

    //log_debug("The data PDU is %s\n", data_buf);
    memset(sms_buf, 0, sms_buf_len);
    if(encoding)
    {
        retval = unicode_to_utf8(data_buf, sizeof(data_buf), sms_buf, sms_buf_len);
    }
    else
    {
        text_decod(start_ptr, sms_buf, data_len);
        
    }

    printf("SMS:%s\n", sms_buf);
    
    return 0;
}


